// 加载图片
import axios from 'axios'
import { storage } from '@/utils/Storage'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import { message } from 'ant-design-vue'
import { getAppEnvConfig } from '@/utils/env'
import { blobFileDownload } from '@@/utils/index'
import { fileExtension } from '@@/api/common/index'
import { Base64 } from 'js-base64'
import streamSaver from 'streamsaver'
streamSaver.mitm = 'https://ctms.tonoinfo.com/common/static/mitm.v2.0.0.html'
type previewOptionsType = {
  returnUrl?: boolean
  extension?: any
}
export class UploadAndPreview {
  baseApi: string
  orgId: string

  constructor(baseApi) {
    this.baseApi = baseApi
    this.orgId = storage.get('ORGINFO') ? storage.get('ORGINFO').orgId : ''
  }

  setHeaders(isFormData = false) {
    const appinfo = (window as any)._PUBLIC_UTILS_.getAppInfo()
    const orgInfo = storage.get('ORGINFO')
    const headers = {
      'yootrial-account': orgInfo ? orgInfo.accountId : '0',
      'yootrial-app': appinfo ? appinfo.appId : '0',
      'yootrial-signature': 0,
      'yootrial-timestamp': Date.now(),
      Authorization: 'Bearer' + storage.get(ACCESS_TOKEN)
    }
    if (isFormData) {
      headers['Content-Type'] = 'multipart/form-data'
    }
    return headers
  }

  getFileUrl(fileId, fileName, customApi, extension) {
    const { VITE_GLOB_PRIVIEW_FILE_URL, VITE_GLOB_PRIVIEW_KK_URL, VITE_GLOB_PRIVIEW_PDF_URL } = getAppEnvConfig()
    const timestamp = new Date().getTime()
    let previewUrl = ''
    const fileEncodeName = this.encodeSearchKey(fileName)
    let fileUrl = `${VITE_GLOB_PRIVIEW_FILE_URL}/Rest/doc/file/filePreview?timestamp=${timestamp}&fullfilename=${fileEncodeName}&docId=${fileId}&orgId=${this.orgId}`

    if (extension.toLowerCase() === 'pdf') {
      fileUrl = `${VITE_GLOB_PRIVIEW_FILE_URL}/Rest/doc/file/filePartPreview?docId=${fileId}&orgId=${this.orgId}`
      previewUrl = `${VITE_GLOB_PRIVIEW_PDF_URL}/web/index.html?file=`
    } else if (storage.get('PREIVEW_TYPE') === 'ow365') {
      // 判断是不是kk预览， 应为kkfile需要
      previewUrl = 'https://ow365.cn/?i=17462&ssl=1&furl='
    } else {
      previewUrl = VITE_GLOB_PRIVIEW_KK_URL + '/onlinePreview?url='
      fileUrl = encodeURIComponent(Base64.encode(customApi || fileUrl))
    }
    previewUrl = previewUrl + (customApi || fileUrl)
    return previewUrl
  }

  previewFile(fileId, fileName, customApi?, options: previewOptionsType = {}) {
    if (options.returnUrl) {
      const arr = (fileName || '').split('.')
      const extension = arr[arr.length - 1]
      return this.getFileUrl(fileId, fileName, customApi, extension)
    }
    ; (async () => {
      let extension = ''
      if (options.extension) {
        extension = options.extension
      } else {
        extension = await fileExtension({ docId: fileId })
      }
      const previewUrl = this.getFileUrl(fileId, fileName, customApi, extension)
      window.open(previewUrl, '_blank')
    })()
  }

  getBase64(img: Blob, callback: (base64Url: string) => void) {
    const reader = new FileReader()
    reader.addEventListener('load', () => callback(reader.result as string))
    reader.readAsDataURL(img)
  }

  // 下载图片的接口
  downloadFileApi(fileId, fileName?, callback?, addWatermarkFlag = true) {
    callback = callback || function () { }
    if (!fileId) {
      callback(null)
      return
    }
    const url =
      this.baseApi + `/doc/Rest/doc/file/imgPreviewOrDownload?docId=${fileId}&addWatermarkFlag=${addWatermarkFlag}`
    axios
      .get(url, {
        responseType: 'blob',
        headers: this.setHeaders()
      })
      .then((res) => {
        if (res.data.size !== 85) {
          if (fileName) {
            const blob = new Blob([res.data], {
              //这个里面的data 的二进制文件 创建一个文件对象
              type: 'text/plain;charset=utf-8'
            })
            const downloadElement = document.createElement('a') //创建一个a 虚拟标签
            const href = window.URL.createObjectURL(blob) // 创建下载的链接
            downloadElement.href = href
            fileName = this.encodeSearchKey(fileName)
            downloadElement.download = fileName || '' // 下载后文件名
            document.body.appendChild(downloadElement)
            downloadElement.click() // 点击下载
            document.body.removeChild(downloadElement) // 下载完成移除元素
            window.URL.revokeObjectURL(href)
            callback(href)
          } else {
            callback(window.URL.createObjectURL(new Blob([res.data])))
          }
        } else {
          callback(null)
        }
      })
  }

  // 处理文件名特殊字符
  encodeSearchKey(key) {
    const encodeArr = [
      {
        code: '%',
        encode: '%25'
      },
      {
        code: '?',
        encode: '%3F'
      },
      {
        code: '#',
        encode: '%23'
      },
      {
        code: '&',
        encode: '%26'
      },
      {
        code: '=',
        encode: '%3D'
      }
    ]
    return key.replace(/[%?#&=]/g, ($) => {
      for (const k of encodeArr) {
        if (k.code === $) {
          return k.encode
        }
      }
    })
  }

  // 下载图片的接口
  downloadFileApi2(opt, callback?) {
    const projectId = window.location.href.includes('/projectCenter/project/detail/')
      ? sessionStorage.getItem('__projectId') || ''
      : undefined
    let params = {
      fileId: undefined,
      fileName: undefined,
      outsideUrl: undefined,
      addWatermarkFlag: true,
      projectId,
      businessId: undefined,
      operationType: undefined,
      docId: undefined
    }
    params = Object.assign(params, opt)
    const { fileId, fileName, outsideUrl } = params
    const copyFileName = fileName
    // 下载的时候可以不要fileName, 如果fileName带特殊字符还会报错，就删了
    if ('fileName') {
      delete params.fileName
    }
    params.docId = fileId
    callback = callback || function () { }
    if (!fileId) {
      callback(null)
      return
    }

    let url = this.baseApi + `/doc/Rest/doc/file/imgPreviewOrDownload`
    if (outsideUrl) {
      url = this.baseApi + `/${outsideUrl}`
    }
    const stt: any = []
    for (const key in params) {
      if (params[key] !== null && params[key] !== undefined) {
        stt.push(key + '=' + params[key])
      }
    }
    url = url + '?' + stt.join('&')
    window
      .fetch(url, {
        method: 'GET',
        cache: 'no-cache',
        headers: this.setHeaders() as any
      })
      .then((res) => {
        if (!res.body) {
          message.error('下载失败')
          return
        }

        const fileStream = streamSaver.createWriteStream(copyFileName, {
          size: res.headers.get('content-length')
        })

        const readableStream = res.body
        // more optimized
        if (window.WritableStream && readableStream.pipeTo) {
          return readableStream.pipeTo(fileStream).then(() => {
            console.log('done writing')
            callback()
          })
        }
        ; (window as any).writer = fileStream.getWriter()

        const reader = res.body.getReader()
        const pump = () =>
          reader
            .read()
            .then((res) =>
              res.done ? (window as any).writer.close() : (window as any).writer.write(res.value).then(pump)
            )

        pump()
      })
  }

  // 不需要Token下的下载
  downloadFileApiNoToken(fileId, fileName?, callback?, addWatermarkFlag = true) {
    callback = callback || function () { }
    if (!fileId) {
      callback(null)
      return
    }
    const url = this.baseApi + `/doc/Rest/doc/file/filePreview?docId=${fileId}&addWatermarkFlag=${addWatermarkFlag}`
    axios
      .get(url, {
        responseType: 'blob'
      })
      .then((res) => {
        if (fileName) {
          const fileUrl = window.URL.createObjectURL(new Blob([res.data]))
          const link = document.createElement('a')
          link.style.display = 'none'
          link.href = fileUrl
          link.download = fileName
          document.body.appendChild(link)
          link.click()
          // 释放URL对象所占资源
          window.URL.revokeObjectURL(fileUrl)
          // 用完即删
          document.body.removeChild(link)
          return
        }
        blobFileDownload(res, fileName, callback, 2)
      })
  }

  // 上传图片的接口
  uploadFileApi(formData) {
    return axios
      .post(this.baseApi + '/doc/Rest/doc/file/minioDocUpload/false', formData, {
        headers: this.setHeaders(true)
      })
      .then((res) => {
        if (res.data.code === 'A00000') {
          return Promise.resolve(res.data.data)
        }
        message.error(`${res.data.msg}`)
        return Promise.reject()
      })
      .catch(() => {
        // message.error('上传失败')
        return Promise.reject()
      })
  }
}
